-
-
Notifications
You must be signed in to change notification settings - Fork 852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose Span methods on LoadPixelData and SavePixelData #567
Conversation
Codecov Report
@@ Coverage Diff @@
## master #567 +/- ##
==========================================
+ Coverage 88.62% 88.62% +<.01%
==========================================
Files 843 843
Lines 35549 35550 +1
Branches 2585 2585
==========================================
+ Hits 31504 31506 +2
Misses 3268 3268
+ Partials 777 776 -1
Continue to review full report at Codecov.
|
Ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just the one change and a comment regards a subtle change in behavior. Everything else looks good to me.
@@ -76,7 +76,10 @@ public static TPixel FromRGBA(byte red, byte green, byte blue, byte alpha) | |||
/// </returns> | |||
private static string ToRgbaHex(string hex) | |||
{ | |||
hex = hex.StartsWith("#") ? hex.Substring(1) : hex; | |||
if (hex[0] == '#') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will fail if hex
is an empty string. we should be checking the length > 0 too. Probably should be defensive over nulls as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This methods only caller is guarding against null and empty. I added some tests to verify this behavior.
@@ -853,7 +853,7 @@ private void ProcessScanlineFromPalette<TPixel>(ReadOnlySpan<byte> defilteredSca | |||
where TPixel : struct, IPixel<TPixel> | |||
{ | |||
ReadOnlySpan<byte> newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth); | |||
byte[] pal = this.palette; | |||
ReadOnlySpan<Rgb24> pal = MemoryMarshal.Cast<byte, Rgb24>(this.palette); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't this fail if this.palette
isn't the correct length? just raising this as a subtle change of behavior that might introduce exceptions that previously (potentially incorrectly) allowed.
note: not asking for a change just pointing it out incase someone else thinks its important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only throw if the we try indexing into the palette outside it's bounds.
…& cleanup messages. Also remove the unused message arguments.
Haven't seen this error before or able to reproduce locally. Will force another build to see if it's transient.
|
@@ -33,7 +33,7 @@ public static Image<TPixel> LoadPixelData<TPixel>(TPixel[] data, int width, int | |||
/// <param name="height">The height of the final image.</param> | |||
/// <typeparam name="TPixel">The pixel format.</typeparam> | |||
/// <returns>A new <see cref="Image{TPixel}"/>.</returns> | |||
private static Image<TPixel> LoadPixelData<TPixel>(Span<TPixel> data, int width, int height) | |||
public static Image<TPixel> LoadPixelData<TPixel>(Span<TPixel> data, int width, int height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should consume ReadOnlySpan
in all overloads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake that I also forgot about this in #565 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I'll update the PR shortly. Also need to figure out why that test is failing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
@JimBobSquarePants @antonfirsov Should we remove the LoadFrom / SaveTo array overloads and just expose Span to simplify the API surface? Any downsides? |
Not everyone knows about An other donwside is loosing binary compatiblity, but I don't mind that, because no one cares about binary compatiblity in .NET Core world these days 😆 (At least not before reaching RC.) |
@JimBobSquarePants Ready for your final review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff... One change and a small doco error though please..
@@ -57,7 +57,7 @@ public static Image<TPixel> LoadPixelData<TPixel>(byte[] data, int width, int he | |||
/// <param name="height">The height of the final image.</param> | |||
/// <typeparam name="TPixel">The pixel format.</typeparam> | |||
/// <returns>A new <see cref="Image{TPixel}"/>.</returns> | |||
private static Image<TPixel> LoadPixelData<TPixel>(Span<byte> data, int width, int height) | |||
public static Image<TPixel> LoadPixelData<TPixel>(Span<byte> data, int width, int height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReadOnlySpan<byte>
src/ImageSharp/ImageExtensions.cs
Outdated
where TPixel : struct, IPixel<TPixel> | ||
=> source.Frames.RootFrame.SavePixelData(MemoryMarshal.Cast<byte, TPixel>(buffer)); | ||
|
||
/// <summary> | ||
/// Saves the raw image to the given bytes. | ||
/// Saves the raw image to the given byte buffer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Target buffer is of type TPixel
@@ -42,6 +42,12 @@ internal ImageFrameCollection(Image<TPixel> parent, IEnumerable<ImageFrame<TPixe | |||
this.ValidateFrame(f); | |||
this.frames.Add(f); | |||
} | |||
|
|||
// Ensure at least 1 frame was added to the frames collection | |||
if (this.frames.Count == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we not check this before iterating. Guard.IsTrue(frames.Count > 0)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No count on IEnumerable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Legit, forgot about IEnumerable
.
(byte)(packedValue >> 16), | ||
(byte)(packedValue >> 8), | ||
(byte)(packedValue >> 0)); | ||
var rgba = new Rgba32(BinaryPrimitives.ReverseEndianness(packedValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
|
||
return string.Concat(red, red, green, green, blue, blue, alpha, alpha); | ||
return new string(new[] { r, r, g, g, b, b, a, a }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it.
|
||
namespace SixLabors.ImageSharp.Tests.Colors | ||
{ | ||
public class ColorBuilderTests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
@@ -85,6 +85,13 @@ public void AddImageFormat(IImageFormat format) | |||
/// <returns>The <see cref="IImageFormat"/> if found otherwise null</returns> | |||
public IImageFormat FindFormatByFileExtension(string extension) | |||
{ | |||
Guard.NotNullOrWhiteSpace(extension, nameof(extension)); | |||
|
|||
if (extension[0] == '.') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea!
Prerequisites
Description